#include "common.h"
#pragma once

typedef void (*func_t)(const std::string &name, pthread_mutex_t *pmtx, pthread_cond_t *pcond);

void func1(const std::string &name, pthread_mutex_t *pmtx, pthread_cond_t *pcond)
{
    while (!quit)
    {
        pthread_mutex_lock(pmtx);
        // 一定要在加锁和解锁之间的临界区进行wait！
        // 各线程执行到wait函数时，排队阻塞等待条件变量
        pthread_cond_wait(pcond, pmtx); 
        std::cout << name << " call "
                  << "func1" << std::endl;
        pthread_mutex_unlock(pmtx);
    }
}

void func2(const std::string &name, pthread_mutex_t *pmtx, pthread_cond_t *pcond)
{
    while (!quit)
    {
        pthread_mutex_lock(pmtx);
        pthread_cond_wait(pcond, pmtx); // 各线程执行到wait函数时，排队阻塞等待条件变量
        std::cout << name << " call "
                  << "func2" << std::endl;
        pthread_mutex_unlock(pmtx);
    }
}

void func3(const std::string &name, pthread_mutex_t *pmtx, pthread_cond_t *pcond)
{
    while (!quit)
    {
        pthread_mutex_lock(pmtx);
        // 各线程执行到wait函数时，排队阻塞等待条件变量
        // 一定要在加锁和解锁之间的临界区进行wait！
        pthread_cond_wait(pcond, pmtx); 
        
        std::cout << name << " call "
                  << "func3" << std::endl;
        pthread_mutex_unlock(pmtx);
    }
}

void func4(const std::string &name, pthread_mutex_t *pmtx, pthread_cond_t *pcond)
{
    while (!quit)
    {
        pthread_mutex_lock(pmtx);
        pthread_cond_wait(pcond, pmtx); // 各线程执行到wait函数时，排队阻塞等待条件变量
        std::cout << name << " call "
                  << "func4" << std::endl;
        pthread_mutex_unlock(pmtx);
    }
}

void func5(const std::string &name, pthread_mutex_t *pmtx, pthread_cond_t *pcond)
{
    while (!quit)
    {
        pthread_mutex_lock(pmtx);
        pthread_cond_wait(pcond, pmtx); // 各线程执行到wait函数时，排队阻塞等待条件变量
        std::cout << name << " call "
                  << "func5" << std::endl;
        pthread_mutex_unlock(pmtx);
    }
}

func_t funcs[THREAD_NUM] = {func1, func2, func3, func4, func5};
